#ifndef TILE_TABLE_MODEL_H
#define TILE_TABLE_MODEL_H

#include <QAbstractTableModel>

#include <QMap>
#include <QPixmap>
#include <QPoint>
#include <QPointer>

class AppStateModel;
class TexturePack;
class TileSheet;

class TileTableModel : public QAbstractTableModel {
  Q_OBJECT
 public:
  static const int kTileSheetRole;
  static const int kChosenPackRole;

  explicit TileTableModel(const AppStateModel* app_state,
                          QObject* parent = NULL);

  QString tileSheetName() const;
  TileSheet* tileSheet(const QModelIndex& index) const;
  void setTileSheetName(QString name);

  void setDefaultPack(TexturePack* pack);

  virtual int rowCount(const QModelIndex& parent = QModelIndex()) const;
  virtual int columnCount(const QModelIndex& parent = QModelIndex()) const;

  // Returns the tile pixmap for the given index, taking into account all overrides.
  QPixmap tilePixmap(const QModelIndex& index) const;

  // Read-only access to kTileSheetRole and kChosenPackRole.  Do not call setData(); it will
  // just return false and silently mock your failure.  Call setChosenPack() and
  // setTileSheetName() instead.  (Qt item views are a bit ugly.)
  QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
  QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;

  // Generates and returns a pixmap containing the merged tilesheet as it appears at this moment.
  QPixmap tileSheetPixmap() const;

 public slots:
  TexturePack* chosenPack(const QModelIndex& index) const;
  void setChosenPack(const QModelIndex& index, TexturePack* pack);
  void setChosenPack(const QModelIndexList& indices, TexturePack* pack);
  void chooseNextPack(const QModelIndex& index);

  QPoint tilePositionOverride(const QModelIndex& index) const;
  void setTilePositionOverride(const QModelIndex& index, const QPoint& override);
  void clearTilePositionOverride(const QModelIndex& index);
  void clearTilePositionOverride(const QModelIndexList &indices);

  QPixmap tilePixmapOverride(const QModelIndex& index) const;
  void setTilePixmapOverride(const QModelIndex& index, const QPixmap& override);
  void clearTilePixmapOverride(const QModelIndex& index);
  void clearTilePixmapOverride(const QModelIndexList &indices);

 private:
  const AppStateModel* app_state_model_;
  TexturePack* default_pack_;
  QString tilesheet_name_;

  // Stores which pack is selected for each index.
  QMap<QModelIndex, TexturePack*> selected_packs_;

  // Stores any indices that are using a tile located somewhere other than its default row/column.
  QMap<QModelIndex, QPoint> tile_position_overrides_;

  // Stores any indices that are using a custom pixmap.
  QMap<QModelIndex, QPixmap> tile_pixmap_overrides_;
};

#endif // TILE_TABLE_MODEL_H
